/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

#include <utility>
#include <set>
#include <random>
#include <algorithm>


/* 
 * File:   flatset.hpp
 * Author: jarda
 *
 * Created on 31. prosince 2017, 15:11
 */

/**
 * Note that when the value of an element is changed so that the comparator orders it differently, the behavior is undefined.
 */
template <typename T, typename Comparator>

class flat_set {
public:
    std::vector<T> set=new std::vector<T>;
    Comparator comperator;
    // These types need to be accesible from the outside:
    // iterator
    // const_iterator
    // size_type
    // value_type
    
    // Special member functions
    flat_set(){
        comperator=[] (int a, int b) {return a > b; };
        set={};
    
    };
    flat_set(Comparator const& cmp){
       comperator=cmp;
        
    };
    flat_set(flat_set const& rhs);
    flat_set(flat_set && rhs);
    flat_set& operator=(flat_set const& rhs);
    flat_set& operator=(flat_set && rhs);
    ~flat_set();
    // Constructs flat_set from elements in range [first, last)
    template <typename InputIterator>
    flat_set(InputIterator first, InputIterator last){
        comperator=[] (int a, int b) {return a > b; };
        while (first!=last) {
            insert(*first);
            
            
            first++;
        }
        std::stable_sort(set.begin(),set.end(),comperator);
    
    
    };
    template <typename InputIterator>
    flat_set(InputIterator first, InputIterator last, Comparator const& cmp){
        comperator=cmp;
        while (first!=last) {
               insert(*first);


               first++;
           }
        std::stable_sort(set.begin(),set.end(),comperator);


    
    
    
    };
    class iterator {
       
    };
    class const_iterator{};
    class size_type {};
    class value_type{};
 
    // Insert overloads
    std::pair<iterator, bool> insert(T const& v){
        for(int i=0;i<&set.size();i++){
            if (set.at(i)== v) {
                std::pair<iterator,bool> a= (set.begin(),false);
                return a;
            }

        
        }
        set.push_back(v);
        std::sort(set.begin(),set.end(),comperator);
       std::pair<iterator,bool> a= (set.begin(),true);
       return a;
    };
    std::pair<iterator, bool> insert(T&& v){
     for(int i=0;i<set.size();i++){
            if (set.at(i)== v) {
                std::pair<iterator,bool> a= (set.begin(),false);
                return a;
            }

        
        }
        set.push_back(v);
        std::sort(set.begin(),set.end(),comperator);
        std::pair<iterator,bool> a= (set.begin(),true);
        return a;
    
    
    };
    // Inserts [first, last) range of elements
    template <typename InputIterator>
    void insert(InputIterator first, InputIterator last){
    
        while(first!=last){
            
            for(int i=0;i<set.size();i++){
                if (set.at(i)== *first) {
                    return ;
                }


            }
            set.push_back(*first);
            std::sort(set.begin(),set.end(),comperator);
            
    
            first++;
        
        }
    
    };
 
    // Erase overloads
    // Deletes element pointed-to by i, returns iterator to the next element
    iterator erase(const_iterator i){
        //get index of element, shift everything back one, and fuck the fuck off
    
    
    };
    // Deletes elements in range [first, last), returns iterator to the next element
    iterator erase(const_iterator first, const_iterator last){
            //get index of fisrt element, shift everything back first-last places if you run to the end just stop and fuck the fuck off

    
    };
    // Deletes element equal to key if it is present, returns how many elements were deleted
    size_type erase(value_type const& key){
        //just do the same fucken thing but run through all elements before you do it and repeat the index you at after shiftback delete obvsly 
    
    };
 
    // Iterator member functions
    iterator begin(){
        return set.begin();
    } ;
    iterator end(){
        return set.end();
    } ;
    
    const_iterator cbegin(){return set.cbegin();};
    const_iterator cend(){return set.cend();} ;
 
    // The usual queries
    bool empty(){
        return set.size()==0;
    
    } ;
    size_type size(){
        return set.size();
    
    } ;
    size_type capacity(){
        return set.capacity();
    
    } ;
 
    void reserve(size_type c){
        set.reserve(c);
    
    };
    void clear(){
        set.clear() ;
    
    };
 
    // Lookup member functions
    // Returns iterator to element equivalent to v, or an end iterator if such element is not present
    iterator find(T const& v){
        iterator begin=set.begin();
        while (begin!=set.end()){
            if (*begin==v){
                return begin;
            
            }
        
            begin++;
        }
    
        return begin;
    };
    
 
    // Returns iterator to first element that is not less than t, end iterator if no such element is present
    iterator lower_bound(T const& t){
        iterator beg,end;
        beg=set.begin();
        end=set.end();
        while(beg!=end){
            if(*beg>=t){
                return beg;
            
            }
            beg++;
        }
        return beg;

    };
    
 
    // Returns iterator to first element that is greater than t, end iterator if no such element is present
    iterator upper_bound(T const& t){
         iterator beg,end;
        beg=set.begin();
        end=set.end();
        while(beg!=end){
            if(*beg>t){
                return beg;
            
            }
            beg++;
        }
        return beg;
    
    
    };
   
    
    
 
    void swap(flat_set& o){
        std::vector<T> *a;
        Comparator c;
        a=o.set;
        c=o.comperator;
        o.comperator=this->comperator;
        this->comperator=c;
        o.set=this->set;
        this->set=a;
        
    
    };
  
};

 
// Lexicographical comparisons

template <typename T, typename Comparator>
bool operator==(flat_set<T,Comparator> const& a, flat_set<T,Comparator> const& b){
    std::iterator<T,Comparator> abeg,bbeg,aend,bend;
    abeg=a.set.begin();
    bbeg=b.set.begin();
    bend=b.set.end();
    aend=a.set.end();
    if(a.size()!=b.size()){
        return false;
    
    }
    while(abeg!=aend && bbeg!=bend){
        if(*abeg!=*bbeg){
            return false;
        }
        
    
        abeg++;
        bbeg++;
    }
    return true;
    
};
template <typename T, typename Comparator>
bool operator!=(flat_set<T,Comparator> const& a, flat_set<T,Comparator> const& b){
    return !(a==b);

};
template <typename T, typename Comparator>
bool operator<(flat_set<T,Comparator> const& a, flat_set<T,Comparator> const& b){
    std::iterator<T,Comparator> abeg,bbeg,aend,bend;
    abeg=a.set.begin();
    bbeg=b.set.begin();
    bend=b.set.end();
    aend=a.set.end();
    if(a==b){return false;}
    if(a.size()>b.size()){
        return false;
    
    }
     if(a.size()<b.size()){
        return true;
    
    }
    while(abeg!=aend && bbeg!=bend){
        if(*abeg>*bbeg){
            return false;
        }
        
    
        abeg++;
        bbeg++;
    }
    return true;
    

};
template <typename T, typename Comparator>
bool operator<=(flat_set<T,Comparator> const& a, flat_set<T,Comparator> const& b){
    return(a==b || a<b);
};
template <typename T, typename Comparator>
bool operator>=(flat_set<T,Comparator> const& a, flat_set<T,Comparator> const& b){
    return!(a<b);

};
template <typename T, typename Comparator>
bool operator>(flat_set<T,Comparator> const& a, flat_set<T,Comparator> const& b){
    return(!(a==b) && !(a<b));

};
 
template <typename T,typename Comparator>
void swap(flat_set<T,Comparator> const& a, flat_set<T,Comparator> const& b){a.swap(b);};

